package wallet

import (
	"context"
	"go.uber.org/zap"
	apiAuth "navi-mumbai/app/api/admin/internal/auth"
	pb2 "navi-mumbai/app/rpc/pay/pb"
	"navi-mumbai/app/rpc/wallet/pb"
	"navi-mumbai/common/ctxdata"
	"navi-mumbai/common/key/dbkey"
	"navi-mumbai/common/key/walletkey"
	"navi-mumbai/common/xerr"

	"navi-mumbai/app/api/admin/internal/svc"
	"navi-mumbai/app/api/admin/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type AuditUserWithdrawFlowLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewAuditUserWithdrawFlowLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AuditUserWithdrawFlowLogic {
	return &AuditUserWithdrawFlowLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *AuditUserWithdrawFlowLogic) AuditUserWithdrawFlow(req *types.AuditUserWithdrawReq) (resp *types.AuditUserWithdrawResp, err error) {
	// verify permission level
	adminUid := ctxdata.GetUidFromCtx(l.ctx)
	level := ctxdata.GetAdminPermissionLevelFromCtx(l.ctx)
	if !l.svcCtx.Auth.VerifyPermissionLevel(l.ctx, apiAuth.AdminAuditUserWithdrawApi, adminUid, level) {
		return nil, xerr.NewGrpcErrCodeMsg(xerr.AuthFail, "permission denied")
	}
	switch req.State {
	case dbkey.Enable:
		req.State = walletkey.WithdrawFlowStateAuditPass
	case dbkey.Disable:
		req.State = walletkey.WithdrawFlowStateAuditReject
	default:
		return nil, xerr.NewGrpcErrCodeMsg(xerr.RequestParamError, "invalid state")
	}
	// log
	defer func() {
		apiAuth.WriteAdminLog(l.ctx, l.svcCtx.ApiLogModel, adminUid, apiAuth.AdminAuditUserWithdrawApi, req, resp, err)
	}()

	if req.State == walletkey.WithdrawFlowStateAuditPass { // 审核通过 开始提现
		return l.auditPass(req)
	}
	// 审核拒绝
	if req.State == walletkey.WithdrawFlowStateAuditReject {
		return l.auditReject(req)
	}
	return
}

func (l *AuditUserWithdrawFlowLogic) auditReject(req *types.AuditUserWithdrawReq) (resp *types.AuditUserWithdrawResp, err error) {
	var in3 pb.UpdateWithdrawResultReq
	in3.FlowNo = req.FlowNo
	in3.State = walletkey.WithdrawFlowStateAuditReject
	in3.Remark = req.AuditMsg
	in3.AdminUid = ctxdata.GetUidFromCtx(l.ctx)

	_, err = l.svcCtx.WalletSysRpc.UpdateWithdrawResult(l.ctx, &in3)
	if err != nil {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}
	return nil, err
}

func (l *AuditUserWithdrawFlowLogic) auditPass(req *types.AuditUserWithdrawReq) (resp *types.AuditUserWithdrawResp, err error) {
	var in pb.QueryWithdrawFlowReq
	in.FlowNo = req.FlowNo

	var rsp *pb.QueryWithdrawFlowResp
	rsp, err = l.svcCtx.WalletAdminRpc.QueryWithdrawFlow(l.ctx, &in)
	if err != nil {
		l.Logger.Errorf("err == ", zap.Error(err))
		return nil, err
	}
	resp = &types.AuditUserWithdrawResp{}

	var in3 pb.UpdateWithdrawResultReq
	// 请求第三方支付
	switch rsp.PayChannelId {
	case walletkey.PayChannelIdEpay18_Bank:
		var in2 pb2.CreateEpay18WithdrawReq
		in2.CurrencyAmount = rsp.CurrencyAmount
		in2.CurrencyType = rsp.CurrencyType
		in2.FlowNo = rsp.FlowNo
		in2.PayChannelId = rsp.PayChannelId
		in2.Uid = rsp.Uid
		in2.AccountName = rsp.AccountName
		in2.BankCardNumber = rsp.BankCardNumber
		in2.BankName = rsp.BankName
		in2.BankCode = rsp.BankCode
		var rsp2 *pb2.CreateEpay18WithdrawResp
		rsp2, err = l.svcCtx.PayUserRpc.CreateEpay18Withdraw(l.ctx, &in2)
		if err != nil {
			l.Logger.Errorf("err == ", zap.Error(err))
			return nil, err
		}

		resp.State = rsp2.State
		resp.ErroMsg = rsp2.ErrMsg

		in3.ExternalFlowNo = rsp2.ExFlowNo
		in3.State = rsp2.State
		in3.FlowNo = rsp.FlowNo
		in3.PayGwFlowNo = rsp2.PayGwFlowNo
		in3.ErrMsg = rsp2.ErrMsg
		in3.Uid = rsp.Uid
		in3.Amount = rsp.CurrencyAmount
		in3.Remark = req.AuditMsg
		in3.AdminUid = ctxdata.GetUidFromCtx(l.ctx)

		_, err = l.svcCtx.WalletSysRpc.UpdateWithdrawResult(l.ctx, &in3)
		if err != nil {
			l.Logger.Errorf("err == ", zap.Error(err))
			return nil, err
		}

	default:
		return nil, xerr.NewGrpcErrCodeMsg(xerr.RequestParamError, "invalid pay channel id")
	}

	return
}
